def eval(self, ctx): obj = to_object(ctx.stack.pop(), ctx.space) with_context = Scope(obj, ctx.space, ctx) # todo actually use the obj to modify the ctx with_context.THIS_BINDING = ctx.THIS_BINDING status = ctx.space.exe.execute_fragment_under_context(with_context, self.beg_label, self.end_label) val, typ, spec = status if typ != 3: # exception ctx.stack.pop() if typ == 0: # normal ctx.stack.append(val) return elif typ == 1: # return ctx.stack.append(spec) return None, None # send return signal elif typ == 2: # jump outside ctx.stack.append(val) return spec elif typ == 3: # exception # throw is made with empty stack as usual raise spec else: raise RuntimeError('Invalid return code')
def eval(self, ctx): obj = to_object(ctx.stack.pop(), ctx.space) with_context = Scope( obj, ctx.space, ctx) # todo actually use the obj to modify the ctx with_context.THIS_BINDING = ctx.THIS_BINDING status = ctx.space.exe.execute_fragment_under_context( with_context, self.beg_label, self.end_label) val, typ, spec = status if typ != 3: # exception ctx.stack.pop() if typ == 0: # normal ctx.stack.append(val) return elif typ == 1: # return ctx.stack.append(spec) return None, None # send return signal elif typ == 2: # jump outside ctx.stack.append(val) return spec elif typ == 3: # exception # throw is made with empty stack as usual raise spec else: raise RuntimeError('Invalid return code')
def __init__(self, name, base, decors): self.name = name self.base = base self.decors = decors self.isScope = True Statement.__init__(self) HasChildren.__init__(self) Scope.__init__(self)
def eval(self, ctx): # 4 different exectution results # 0=normal, 1=return, 2=jump_outside, 3=errors # execute_fragment_under_context returns: # (return_value, typ, jump_loc/error) ctx.stack.pop() # execute try statement try_status = ctx.space.exe.execute_fragment_under_context( ctx, self.try_label, self.catch_label) errors = try_status[1] == 3 # catch if errors and self.catch_variable is not None: # generate catch block context... catch_context = Scope( { self.catch_variable: try_status[2].get_thrown_value( ctx.space) }, ctx.space, ctx) catch_context.THIS_BINDING = ctx.THIS_BINDING catch_status = ctx.space.exe.execute_fragment_under_context( catch_context, self.catch_label, self.finally_label) else: catch_status = None # finally if self.finally_present: finally_status = ctx.space.exe.execute_fragment_under_context( ctx, self.finally_label, self.end_label) else: finally_status = None # now return controls other_status = catch_status or try_status if finally_status is None or (finally_status[1] == 0 and other_status[1] != 0): winning_status = other_status else: winning_status = finally_status val, typ, spec = winning_status if typ == 0: # normal ctx.stack.append(val) return elif typ == 1: # return ctx.stack.append(spec) return None, None # send return signal elif typ == 2: # jump outside ctx.stack.append(val) return spec elif typ == 3: # throw is made with empty stack as usual raise spec else: raise RuntimeError('Invalid return code')
def __init__(self, file, name=None): ScriptElement.__init__(self) HasChildren.__init__(self) Scope.__init__(self) self._file = file self.builtin = False if name: self.name = name else: self.name = "main"
def __init__(self, name, args, decors): Statement.__init__(self) HasChildren.__init__(self) Scope.__init__(self) self.name = name self.args = args self.decors = decors self.locals = [] self.isScope = True a = self.locals.append for arg in self.args: a(arg.id)
def eval(self, ctx): # 4 different exectution results # 0=normal, 1=return, 2=jump_outside, 3=errors # execute_fragment_under_context returns: # (return_value, typ, jump_loc/error) ctx.stack.pop() # execute try statement try_status = ctx.space.exe.execute_fragment_under_context(ctx, self.try_label, self.catch_label) errors = try_status[1] == 3 # catch if errors and self.catch_variable is not None: # generate catch block context... catch_context = Scope({self.catch_variable: try_status[2].get_thrown_value(ctx.space)}, ctx.space, ctx) catch_context.THIS_BINDING = ctx.THIS_BINDING catch_status = ctx.space.exe.execute_fragment_under_context(catch_context, self.catch_label, self.finally_label) else: catch_status = None # finally if self.finally_present: finally_status = ctx.space.exe.execute_fragment_under_context(ctx, self.finally_label, self.end_label) else: finally_status = None # now return controls other_status = catch_status or try_status if finally_status is None or (finally_status[1]==0 and other_status[1]!=0): winning_status = other_status else: winning_status = finally_status val, typ, spec = winning_status if typ == 0: # normal ctx.stack.append(val) return elif typ == 1: # return ctx.stack.append(spec) return None, None # send return signal elif typ == 2: # jump outside ctx.stack.append(val) return spec elif typ == 3: # throw is made with empty stack as usual raise spec else: raise RuntimeError('Invalid return code')
def create_signature(self, ret_type, params, cv): exacts, scores = self.score_signatures(ret_type, params, cv) if len(exacts) > 1: raise Exception('Ambiguous signature ' + str([self.signatures[i] for i in exacts])) if len(exacts) == 1: return exacts[0] if len(exacts) == 0: print "No exact match. close matches", scores self.signatures.append((ret_type, [p.type for p in params], cv)) ret = len(self.signatures) - 1 scope = Scope(None, self.owner) self.scopes.append(scope) for p in params: scope.add(p) return ret
def fill_space(space, byte_generator): # set global scope global_scope = Scope({}, space, parent=None) global_scope.THIS_BINDING = global_scope global_scope.registers(byte_generator.declared_vars) space.GlobalObj = global_scope space.byte_generator = byte_generator # first init all protos, later take care of constructors and details # Function must be first obviously, we have to use a small trick to do that... function_proto = space.NewFunction(Empty, space.ctx, (), 'Empty', False, ()) space.FunctionPrototype = function_proto # this will fill the prototypes of the methods! fill_proto(function_proto, FunctionPrototype, space) # Object next object_proto = space.NewObject() # no proto fill_proto(object_proto, ObjectPrototype, space) space.ObjectPrototype = object_proto function_proto.prototype = object_proto # Number number_proto = space.NewObject() number_proto.prototype = object_proto fill_proto(number_proto, NumberPrototype, space) number_proto.value = 0. number_proto.Class = 'Number' space.NumberPrototype = number_proto # String string_proto = space.NewObject() string_proto.prototype = object_proto fill_proto(string_proto, StringPrototype, space) string_proto.value = u'' string_proto.Class = 'String' space.StringPrototype = string_proto # Boolean boolean_proto = space.NewObject() boolean_proto.prototype = object_proto fill_proto(boolean_proto, BooleanPrototype, space) boolean_proto.value = False boolean_proto.Class = 'Boolean' space.BooleanPrototype = boolean_proto # Array array_proto = space.NewArray(0) array_proto.prototype = object_proto fill_proto(array_proto, ArrayPrototype, space) space.ArrayPrototype = array_proto # JSON json = space.NewObject() json.put(u'stringify', easy_func(jsjson.stringify, space)) json.put(u'parse', easy_func(jsjson.parse, space)) # Utils parseFloat = easy_func(jsutils.parseFloat, space) parseInt = easy_func(jsutils.parseInt, space) isNaN = easy_func(jsutils.isNaN, space) isFinite = easy_func(jsutils.isFinite, space) # Error error_proto = space.NewError(u'Error', u'') error_proto.prototype = object_proto error_proto.put(u'name', u'Error') fill_proto(error_proto, ErrorPrototype, space) space.ErrorPrototype = error_proto def construct_constructor(typ): def creator(this, args): message = get_arg(args, 0) if not is_undefined(message): msg = to_string(message) else: msg = u'' return space.NewError(typ, msg) j = easy_func(creator, space) j.name = unicode(typ) j.prototype = space.ERROR_TYPES[typ] def new_create(args, space): message = get_arg(args, 0) if not is_undefined(message): msg = to_string(message) else: msg = u'' return space.NewError(typ, msg) j.create = new_create return j # fill remaining error types error_constructors = {} for err_type_name in (u'Error', u'EvalError', u'RangeError', u'ReferenceError', u'SyntaxError', u'TypeError', u'URIError'): extra_err = space.NewError(u'Error', u'') extra_err.put(u'name', err_type_name) setattr(space, err_type_name + u'Prototype', extra_err) error_constructors[err_type_name] = construct_constructor( err_type_name) assert space.TypeErrorPrototype is not None # RegExp regexp_proto = space.NewRegExp(u'(?:)', u'') regexp_proto.prototype = object_proto fill_proto(regexp_proto, RegExpPrototype, space) space.RegExpPrototype = regexp_proto # Json # now all these boring constructors... # Number number = easy_func(jsnumber.Number, space) space.Number = number number.create = jsnumber.NumberConstructor set_non_enumerable(number_proto, 'constructor', number) set_protected(number, 'prototype', number_proto) # number has some extra constants for k, v in jsnumber.CONSTS.items(): set_protected(number, k, v) # String string = easy_func(jsstring.String, space) space.String = string string.create = jsstring.StringConstructor set_non_enumerable(string_proto, 'constructor', string) set_protected(string, 'prototype', string_proto) # string has an extra function set_non_enumerable(string, 'fromCharCode', easy_func(jsstring.fromCharCode, space)) # Boolean boolean = easy_func(jsboolean.Boolean, space) space.Boolean = boolean boolean.create = jsboolean.BooleanConstructor set_non_enumerable(boolean_proto, 'constructor', boolean) set_protected(boolean, 'prototype', boolean_proto) # Array array = easy_func(jsarray.Array, space) space.Array = array array.create = jsarray.ArrayConstructor set_non_enumerable(array_proto, 'constructor', array) set_protected(array, 'prototype', array_proto) array.put(u'isArray', easy_func(jsarray.isArray, space)) # RegExp regexp = easy_func(jsregexp.RegExp, space) space.RegExp = regexp regexp.create = jsregexp.RegExpCreate set_non_enumerable(regexp_proto, 'constructor', regexp) set_protected(regexp, 'prototype', regexp_proto) # Object _object = easy_func(jsobject.Object, space) space.Object = _object _object.create = jsobject.ObjectCreate set_non_enumerable(object_proto, 'constructor', _object) set_protected(_object, 'prototype', object_proto) fill_proto(_object, jsobject.ObjectMethods, space) # Function function = easy_func(jsfunction.Function, space) space.Function = function # Math math = space.NewObject() math.Class = 'Math' fill_proto(math, jsmath.MathFunctions, space) for k, v in jsmath.CONSTANTS.items(): set_protected(math, k, v) console = space.NewObject() fill_proto(console, jsconsole.ConsoleMethods, space) # set global object builtins = { 'String': string, 'Number': number, 'Boolean': boolean, 'RegExp': regexp, 'exports': convert_to_js_type({}, space), 'Math': math, #'Date', 'Object': _object, 'Function': function, 'JSON': json, 'Array': array, 'parseFloat': parseFloat, 'parseInt': parseInt, 'isFinite': isFinite, 'isNaN': isNaN, 'eval': easy_func(jsfunction._eval, space), 'console': console, 'log': console.get(u'log'), } builtins.update(error_constructors) set_protected(global_scope, 'NaN', NaN) set_protected(global_scope, 'Infinity', Infinity) for k, v in builtins.items(): set_non_enumerable(global_scope, k, v)
def __init__(self, name, scope): Scope.__init__(self, name, scope) print "new StructuredType", name, scope