private void performFunctionDeclarationBindings( final JSCode code, final boolean configurableBindings) { // 10.5 Function Declaration Binding List<FunctionDeclaration> decls = code.getFunctionDeclarations(); EnvironmentRecord env = this.variableEnvironment.getRecord(); for (FunctionDeclaration each : decls) { String identifier = each.getIdentifier(); if (!env.hasBinding(this, identifier)) { env.createMutableBinding(this, identifier, configurableBindings); } else if (env.isGlobal()) { JSObject globalObject = ((ObjectEnvironmentRecord) env).getBindingObject(); PropertyDescriptor existingProp = (PropertyDescriptor) globalObject.getProperty(this, identifier); if (existingProp.isConfigurable()) { PropertyDescriptor newProp = new PropertyDescriptor() { { set("Value", Types.UNDEFINED); set("Writable", true); set("Enumerable", true); set("Configurable", configurableBindings); } }; globalObject.defineOwnProperty(this, identifier, newProp, true); } else if (existingProp.isAccessorDescriptor() || (!existingProp.isWritable() && !existingProp.isEnumerable())) { throw new ThrowException( this, createTypeError("unable to bind function '" + identifier + "'")); } } JSFunction function = getCompiler() .compileFunction( this, identifier, each.getFormalParameters(), each.getBlock(), each.isStrict()); function.setDebugContext(identifier); env.setMutableBinding(this, identifier, function, code.isStrict()); } }
protected Object primitiveGet(ExecutionContext context, JSObject o, String name) { // 8.7.1 primitive [[Get]] Object d = o.getProperty(context, name, false); if (d == Types.UNDEFINED) { return Types.UNDEFINED; } PropertyDescriptor desc = (PropertyDescriptor) d; if (desc.isDataDescriptor()) { Object value = desc.getValue(); if (value == null) { value = Types.UNDEFINED; } return value; } Object getter = desc.getGetter(); if (getter == Types.UNDEFINED) { return Types.UNDEFINED; } return context.call((JSFunction) getter, o); }