| Index: src/builtins.cc
|
| ===================================================================
|
| --- src/builtins.cc (revision 4955)
|
| +++ src/builtins.cc (working copy)
|
| @@ -1377,74 +1377,109 @@
|
| }
|
| #endif
|
|
|
| -Object* Builtins::builtins_[builtin_count] = { NULL, };
|
| -const char* Builtins::names_[builtin_count] = { NULL, };
|
|
|
| +Builtins::Builtins() {
|
| + memset(builtins_, 0, sizeof(builtins_[0]) * builtin_count);
|
| + memset(names_, 0, sizeof(names_[0]) * builtin_count);
|
| +}
|
| +
|
| +
|
| +Builtins::~Builtins() {
|
| +}
|
| +
|
| +
|
| #define DEF_ENUM_C(name, ignore) FUNCTION_ADDR(Builtin_##name),
|
| - Address Builtins::c_functions_[cfunction_count] = {
|
| - BUILTIN_LIST_C(DEF_ENUM_C)
|
| - };
|
| +Address const Builtins::c_functions_[cfunction_count] = {
|
| + BUILTIN_LIST_C(DEF_ENUM_C)
|
| +};
|
| #undef DEF_ENUM_C
|
|
|
| #define DEF_JS_NAME(name, ignore) #name,
|
| #define DEF_JS_ARGC(ignore, argc) argc,
|
| -const char* Builtins::javascript_names_[id_count] = {
|
| +const char* const Builtins::javascript_names_[id_count] = {
|
| BUILTINS_LIST_JS(DEF_JS_NAME)
|
| };
|
|
|
| -int Builtins::javascript_argc_[id_count] = {
|
| +int const Builtins::javascript_argc_[id_count] = {
|
| BUILTINS_LIST_JS(DEF_JS_ARGC)
|
| };
|
| #undef DEF_JS_NAME
|
| #undef DEF_JS_ARGC
|
|
|
| -static bool is_initialized = false;
|
| -void Builtins::Setup(bool create_heap_objects) {
|
| - ASSERT(!is_initialized);
|
| +struct BuiltinDesc {
|
| + byte* generator;
|
| + byte* c_code;
|
| + const char* s_name; // name is only used for generating log information.
|
| + int name;
|
| + Code::Flags flags;
|
| + BuiltinExtraArguments extra_args;
|
| +};
|
|
|
| - // Create a scope for the handles in the builtins.
|
| - HandleScope scope;
|
| +class BuiltinFunctionTable {
|
| + public:
|
| + BuiltinFunctionTable() {
|
| + Builtins::InitBuiltinFunctionTable();
|
| + }
|
|
|
| - struct BuiltinDesc {
|
| - byte* generator;
|
| - byte* c_code;
|
| - const char* s_name; // name is only used for generating log information.
|
| - int name;
|
| - Code::Flags flags;
|
| - BuiltinExtraArguments extra_args;
|
| - };
|
| + static const BuiltinDesc* functions() { return functions_; }
|
|
|
| -#define DEF_FUNCTION_PTR_C(name, extra_args) \
|
| - { FUNCTION_ADDR(Generate_Adaptor), \
|
| - FUNCTION_ADDR(Builtin_##name), \
|
| - #name, \
|
| - c_##name, \
|
| - Code::ComputeFlags(Code::BUILTIN), \
|
| - extra_args \
|
| - },
|
| + private:
|
| + static BuiltinDesc functions_[Builtins::builtin_count + 1];
|
|
|
| -#define DEF_FUNCTION_PTR_A(name, kind, state) \
|
| - { FUNCTION_ADDR(Generate_##name), \
|
| - NULL, \
|
| - #name, \
|
| - name, \
|
| - Code::ComputeFlags(Code::kind, NOT_IN_LOOP, state), \
|
| - NO_EXTRA_ARGUMENTS \
|
| - },
|
| + friend class Builtins;
|
| +};
|
|
|
| - // Define array of pointers to generators and C builtin functions.
|
| - static BuiltinDesc functions[] = {
|
| - BUILTIN_LIST_C(DEF_FUNCTION_PTR_C)
|
| - BUILTIN_LIST_A(DEF_FUNCTION_PTR_A)
|
| - BUILTIN_LIST_DEBUG_A(DEF_FUNCTION_PTR_A)
|
| - // Terminator:
|
| - { NULL, NULL, NULL, builtin_count, static_cast<Code::Flags>(0),
|
| - NO_EXTRA_ARGUMENTS }
|
| - };
|
| +BuiltinDesc BuiltinFunctionTable::functions_[Builtins::builtin_count + 1];
|
|
|
| +static const BuiltinFunctionTable builtin_function_table_init;
|
| +
|
| +// Define array of pointers to generators and C builtin functions.
|
| +// We do this in a sort of roundabout way so that we can do the initialization
|
| +// within the lexical scope of Builtins:: and within a context where
|
| +// Code::Flags names a non-abstract type.
|
| +void Builtins::InitBuiltinFunctionTable() {
|
| + BuiltinDesc* functions = BuiltinFunctionTable::functions_;
|
| + functions[builtin_count].generator = NULL;
|
| + functions[builtin_count].c_code = NULL;
|
| + functions[builtin_count].s_name = NULL;
|
| + functions[builtin_count].name = builtin_count;
|
| + functions[builtin_count].flags = static_cast<Code::Flags>(0);
|
| + functions[builtin_count].extra_args = NO_EXTRA_ARGUMENTS;
|
| +
|
| +#define DEF_FUNCTION_PTR_C(aname, aextra_args) \
|
| + functions->generator = FUNCTION_ADDR(Generate_Adaptor); \
|
| + functions->c_code = FUNCTION_ADDR(Builtin_##aname); \
|
| + functions->s_name = #aname; \
|
| + functions->name = c_##aname; \
|
| + functions->flags = Code::ComputeFlags(Code::BUILTIN); \
|
| + functions->extra_args = aextra_args; \
|
| + ++functions;
|
| +
|
| +#define DEF_FUNCTION_PTR_A(aname, kind, state) \
|
| + functions->generator = FUNCTION_ADDR(Generate_##aname); \
|
| + functions->c_code = NULL; \
|
| + functions->s_name = #aname; \
|
| + functions->name = aname; \
|
| + functions->flags = Code::ComputeFlags(Code::kind, NOT_IN_LOOP, state); \
|
| + functions->extra_args = NO_EXTRA_ARGUMENTS; \
|
| + ++functions;
|
| +
|
| + BUILTIN_LIST_C(DEF_FUNCTION_PTR_C)
|
| + BUILTIN_LIST_A(DEF_FUNCTION_PTR_A)
|
| + BUILTIN_LIST_DEBUG_A(DEF_FUNCTION_PTR_A)
|
| +
|
| #undef DEF_FUNCTION_PTR_C
|
| #undef DEF_FUNCTION_PTR_A
|
| +}
|
|
|
| +void Builtins::Setup(bool create_heap_objects) {
|
| + ASSERT(!initialized_);
|
| +
|
| + // Create a scope for the handles in the builtins.
|
| + HandleScope scope;
|
| +
|
| + const BuiltinDesc* functions = BuiltinFunctionTable::functions();
|
| +
|
| // For now we generate builtin adaptor code into a stack-allocated
|
| // buffer, before copying it into individual code objects.
|
| byte buffer[4*KB];
|
| @@ -1494,12 +1529,12 @@
|
| }
|
|
|
| // Mark as initialized.
|
| - is_initialized = true;
|
| + initialized_ = true;
|
| }
|
|
|
|
|
| void Builtins::TearDown() {
|
| - is_initialized = false;
|
| + initialized_ = false;
|
| }
|
|
|
|
|
| @@ -1509,7 +1544,8 @@
|
|
|
|
|
| const char* Builtins::Lookup(byte* pc) {
|
| - if (is_initialized) { // may be called during initialization (disassembler!)
|
| + // may be called during initialization (disassembler!)
|
| + if (initialized_) {
|
| for (int i = 0; i < builtin_count; i++) {
|
| Code* entry = Code::cast(builtins_[i]);
|
| if (entry->contains(pc)) {
|
|
|