Skip to content

Instantly share code, notes, and snippets.

@michaelwu
Last active December 3, 2015 00:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michaelwu/1fd27eb7891daf2ead15 to your computer and use it in GitHub Desktop.
Save michaelwu/1fd27eb7891daf2ead15 to your computer and use it in GitHub Desktop.
Self hosted TS
/// <reference path="selfhosted.d.ts"/>
// Integer conversions
function WebidlEnforceRange(val, min, max) {
var num = ToNumber(val);
if (!Number_isFinite(num))
ThrowTypeError("Value isn't finite!");
if (val < 0)
num = -std_Math_floor(std_Math_abs(num));
else
num = std_Math_floor(std_Math_abs(num));
if (num < min || num > max)
ThrowTypeError("Value is out of range");
return num;
}
function WebidlClamp(val, min, max) {
var num = ToNumber(val);
if (Number_isNaN(num))
return 0;
num = std_Math_min(std_Math_max(num, min), max);
var to_truncate = num + 0.5;
num = num | 0;
if (to_truncate == num) {
return num & ~1;
}
return num;
}
function ToWebidlByte(val) {
var num = (val >>> 0) % (1 << 8);
if (num >= (1 << 7))
return num - (1 << 8);
return num;
}
function ToWebidlByteEnforceRange(val) {
return WebidlEnforceRange(val, -(1 << 7), (1 << 7) - 1);
}
function ToWebidlByteClamp(val) {
return WebidlClamp(val, -(1 << 7), (1 << 7) - 1);
}
function ToWebidlOctet(val) {
return (val >>> 0) % (1 << 8);
}
function ToWebidlOctetEnforceRange(val) {
return WebidlEnforceRange(val, 0, (1 << 8) - 1);
}
function ToWebidlOctetClamp(val) {
return WebidlClamp(val, 0, (1 << 8) - 1);
}
function ToWebidlShort(val) {
var num = (val >>> 0) % (1 << 16);
if (num >= (1 << 15))
return num - (1 << 16);
return num;
}
function ToWebidlShortEnforceRange(val) {
return WebidlEnforceRange(val, -(1 << 15), (1 << 15) - 1);
}
function ToWebidlShortClamp(val) {
return WebidlClamp(val, -(1 << 15), (1 << 15) - 1);
}
function ToWebidlUnsignedShort(val) {
return (val >>> 0) % (1 << 16);
}
function ToWebidlUnsignedShortEnforceRange(val) {
return WebidlEnforceRange(val, 0, (1 << 16) - 1);
}
function ToWebidlUnsignedShortClamp(val) {
return WebidlClamp(val, 0, (1 << 16) - 1);
}
function ToWebidlLong(val) {
return val | 0;
}
function ToWebidlLongEnforceRange(val) {
return WebidlEnforceRange(val, -(1 << 31), (1 << 31) - 1);
}
function ToWebidlLongClamp(val) {
return WebidlClamp(val, -(1 << 31), (1 << 31) - 1);
}
function ToWebidlUnsignedLong(val) {
return val >>> 0;
}
function ToWebidlUnsignedLongEnforceRange(val) {
return WebidlEnforceRange(val, 0, ~0 >>> 0);
}
function ToWebidlUnsignedLongClamp(val) {
return WebidlClamp(val, 0, ~0 >>> 0);
}
// XXX add long long conversions
function ToWebidlFloat(val) {
var num = ToNumber(val);
if (!Number_isFinite(num))
ThrowTypeError("Value must be finite");
var rval = std_Math_fround(num);
// XXX Check and throw on 2 ^ 128
if (rval === 0.0 && num < 0)
rval = -0.0;
return rval;
}
function ToWebidlUnrestrictedFloat(val) {
var num = ToNumber(val);
if (!Number_isFinite(num))
ThrowTypeError("Value must be finite");
var rval = std_Math_fround(num);
// XXX Check for 2 ^ 128 and return infinity if so
if (rval === 0.0 && num < 0)
rval = -0.0;
return rval;
}
function ToWebidlDouble(val) {
var num = ToNumber(val);
if (!Number_isFinite(num))
ThrowTypeError("Value must be finite");
return num;
}
function ToWebidlByteString(val) {
var str = ToString(val);
for (var i = 0; i < str.length; i++) {
if (callFunction(std_String_charCodeAt, str, i) > 255)
ThrowTypeError("Value at " + i + "is greater than 255");
}
return str;
}
function ToWebidlObject(val) {
if (!IsObject(val))
ThrowTypeError("Value is not an object");
return val;
}
class Node {
constructor(obj) {
this.obj = obj;
}
get parent_node() { return UnsafeGetReservedSlot(this.obj, 1); }
get first_child() { return UnsafeGetReservedSlot(this.obj, 2); }
get last_child() { return UnsafeGetReservedSlot(this.obj, 3); }
get next_sibling() { return UnsafeGetReservedSlot(this.obj, 4); }
get prev_sibling() { return UnsafeGetReservedSlot(this.obj, 5); }
get owner_doc() { return UnsafeGetReservedSlot(this.obj, 6); }
get child_list() { return UnsafeGetReservedSlot(this.obj, 7); }
set child_list(val) { UnsafeSetReservedSlot(this.obj, 7, val); }
get children_count() { return UnsafeGetReservedSlot(this.obj, 8); }
get flags() { return UnsafeGetInt32FromReservedSlot(this.obj, 9); }
get layout_data() { return UnsafeGetReservedSlot(this.obj, 10); }
get unique_id() { return UnsafeGetStringFromReservedSlot(this.obj, 11); }
}
function NodeImpl_fn_hasChildNodes(self) {
return !!self.first_child;
}
function NodeImpl_get_firstChild(self) {
return self.first_child;
}
/// <reference path="webidl_conversions.ts"/>
/// <reference path="slot_defs.ts"/>
/// <reference path="node.ts"/>
function Node_fn_hasChildNodes() {
if (!CheckDOMProtochain(this, 112, 1))
ThrowTypeError("\"this\" object does not implement interface Node.");
return NodeImpl_fn_hasChildNodes(new Node(this));
}
function Node_get_firstChild() {
if (!CheckDOMProtochain(this, 112, 1))
ThrowTypeError("\"this\" object does not implement interface Node.");
return NodeImpl_get_firstChild(new Node(this));
}
diff --git a/mozjs/js/src/vm/SelfHosting.cpp b/mozjs/js/src/vm/SelfHosting.cpp
index 4395c09..3cc6f73 100644
--- a/mozjs/js/src/vm/SelfHosting.cpp
+++ b/mozjs/js/src/vm/SelfHosting.cpp
@@ -875,6 +875,23 @@ intrinsic_ConstructorForTypedArray(JSContext *cx, unsigned argc, Value *vp)
return true;
}
+static bool intrinsic_CheckDOMProtochain(JSContext *cx, unsigned argc, Value *vp)
+{
+ CallArgs args = CallArgsFromVp(argc, vp);
+ MOZ_ASSERT(args.length() == 3);
+ MOZ_ASSERT(args[0].isObject());
+ MOZ_ASSERT(args[1].isInt32());
+ MOZ_ASSERT(args[2].isInt32());
+
+ RootedObject object(cx, &args[0].toObject());
+ const Class *clasp = object->getClass();
+ bool match = clasp->isDOMClass() &&
+ cx->runtime()->DOMcallbacks->instanceClassMatchesProto(
+ clasp, args[1].toInt32(), args[2].toInt32());
+ args.rval().setBoolean(match);
+ return true;
+}
+
// The self-hosting global isn't initialized with the normal set of builtins.
// Instead, individual C++-implemented functions that're required by
// self-hosted code are defined as global functions. Accessing these
@@ -1071,6 +1088,8 @@ static const JSFunctionSpec intrinsic_functions[] = {
JS_FN("regexp_test_no_statics", regexp_test_no_statics, 2,0),
JS_FN("regexp_construct_no_statics", regexp_construct_no_statics, 2,0),
+ JS_FN("CheckDOMProtochain", intrinsic_CheckDOMProtochain, 3, 0),
+
JS_FS_END
};
/// <reference no-default-lib="true"/>
declare function IsObject(v: any): boolean;
declare function ToNumber(v: any): number;
declare function ToString(v: any): string;
declare function Number_isFinite(v: any): boolean;
declare function Number_isNaN(v: any): boolean;
declare function std_Math_abs(v: any): number;
declare function std_Math_floor(v: any): number;
declare function std_Math_fround(v: any): number;
declare function std_Math_min(v1: any, v2: any): number;
declare function std_Math_max(v1: any, v2: any): number;
declare function ThrowTypeError(v: any): void;
declare function std_String_charCodeAt(v: string, idx: any): number;
declare function callFunction<T>(func: (...args: any[]) => T, ...args: any[]): T;
interface Array<T> {
}
interface Boolean {
}
interface Function {
}
interface IArguments {
length: number;
}
interface Number {
}
interface Object {
}
interface RegExp {
}
interface String {
length: number;
}
/// <reference path="selfhosted.d.ts"/>
// Integer conversions
function WebidlEnforceRange(val, min, max): number {
var num = ToNumber(val);
if (!Number_isFinite(num))
ThrowTypeError("Value isn't finite!");
if (val < 0)
num = -std_Math_floor(std_Math_abs(num));
else
num = std_Math_floor(std_Math_abs(num));
if (num < min || num > max)
ThrowTypeError("Value is out of range");
return num;
}
function WebidlClamp(val, min, max): number {
var num = ToNumber(val);
if (Number_isNaN(num))
return 0;
num = std_Math_min(std_Math_max(num, min), max);
var to_truncate = num + 0.5;
num = num | 0;
if (to_truncate == num) {
return num & ~1;
}
return num;
}
function ToWebidlByte(val): number {
var num = (val >>> 0) % (1 << 8);
if (num >= (1 << 7))
return num - (1 << 8);
return num;
}
function ToWebidlByteEnforceRange(val): number {
return WebidlEnforceRange(val, -(1 << 7), (1 << 7) - 1);
}
function ToWebidlByteClamp(val): number {
return WebidlClamp(val, -(1 << 7), (1 << 7) - 1);
}
function ToWebidlOctet(val): number {
return (val >>> 0) % (1 << 8);
}
function ToWebidlOctetEnforceRange(val): number {
return WebidlEnforceRange(val, 0, (1 << 8) - 1);
}
function ToWebidlOctetClamp(val): number {
return WebidlClamp(val, 0, (1 << 8) - 1);
}
function ToWebidlShort(val): number {
var num = (val >>> 0) % (1 << 16);
if (num >= (1 << 15))
return num - (1 << 16);
return num;
}
function ToWebidlShortEnforceRange(val): number {
return WebidlEnforceRange(val, -(1 << 15), (1 << 15) - 1);
}
function ToWebidlShortClamp(val): number {
return WebidlClamp(val, -(1 << 15), (1 << 15) - 1);
}
function ToWebidlUnsignedShort(val): number {
return (val >>> 0) % (1 << 16);
}
function ToWebidlUnsignedShortEnforceRange(val): number {
return WebidlEnforceRange(val, 0, (1 << 16) - 1);
}
function ToWebidlUnsignedShortClamp(val): number {
return WebidlClamp(val, 0, (1 << 16) - 1);
}
function ToWebidlLong(val): number {
return val | 0;
}
function ToWebidlLongEnforceRange(val): number {
return WebidlEnforceRange(val, -(1 << 31), (1 << 31) - 1);
}
function ToWebidlLongClamp(val): number {
return WebidlClamp(val, -(1 << 31), (1 << 31) - 1);
}
function ToWebidlUnsignedLong(val): number {
return val >>> 0;
}
function ToWebidlUnsignedLongEnforceRange(val): number {
return WebidlEnforceRange(val, 0, ~0 >>> 0);
}
function ToWebidlUnsignedLongClamp(val): number {
return WebidlClamp(val, 0, ~0 >>> 0);
}
// XXX add long long conversions
function ToWebidlFloat(val): number {
var num = ToNumber(val);
if (!Number_isFinite(num))
ThrowTypeError("Value must be finite");
var rval = std_Math_fround(num);
// XXX Check and throw on 2 ^ 128
if (rval === 0.0 && num < 0)
rval = -0.0;
return rval;
}
function ToWebidlUnrestrictedFloat(val): number {
var num = ToNumber(val);
if (!Number_isFinite(num))
ThrowTypeError("Value must be finite");
var rval = std_Math_fround(num);
// XXX Check for 2 ^ 128 and return infinity if so
if (rval === 0.0 && num < 0)
rval = -0.0;
return rval;
}
function ToWebidlDouble(val): number {
var num = ToNumber(val);
if (!Number_isFinite(num))
ThrowTypeError("Value must be finite");
return num;
}
function ToWebidlByteString(val): string {
var str = ToString(val);
for (var i = 0; i < str.length; i++) {
if (callFunction(std_String_charCodeAt, str, i) > 255)
ThrowTypeError("Value at " + i + "is greater than 255");
}
return str;
}
function ToWebidlObject(val): Object {
if (!IsObject(val))
ThrowTypeError("Value is not an object");
return val;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment